#!/bin/bash

#    ICTrash - IceCoder's trash-can manager.
#    Copyright (C) 2011 Alfredo 'IceCoder' Mungo
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

if [ -f ~/.icetoolsrc ] ; then
  . ~/.icetoolsrc
else
  echo "No config file detected, please run ic_setup first."
  exit
fi

if [ ! -d $trashdir ] ; then
  echo Directory $trashdir does not exist, please create it in order to use the trash-can.
fi

if [ ! -d $trashdir/files ] ; then
  echo Directory $trashdir/files does not exist, please create it in order to use the trash-can.
fi

if [ ! -d $trashdir/info ] ; then
  echo Directory $trashdir/info does not exist, please create it in order to use the trash-can.
fi

function trashHelp
{
  echo "IceCoder's trash handler"
  echo "Usage: ic_trash {command} [args]"
  echo
  echo "Commands:"
  echo -e "\tdisplay: Displays the content of the trash-can.\n"
  echo -e "\tinfo: Displays trashed files information.\n"
  echo -e "\tdelete FILENAME: Deletes FILENAME permanently.\n"
  echo -e "\ttrash FILENAME(s): Moves FILENAME(s) to the trash-can.\n"
  echo -e "\trestore FILENAME: Restores FILENAME from the trash-can.\n"
  echo -e "\tempty [-y]: empties the trash-can. If '-y' is appended, no question will be provided."
  echo
}

function trashDisplay
{
  echo "Trash-can content for user $USER:"

  for f in $trashdir/files/* ; do
  
    local a=`echo $f | sed s!$trashdir/files/!!`
    if [ "$a" = "*" ] ; then
      echo The trash-can is empty.
      exit
    fi
    
    if [ -d $f ] ; then
      echo -e "DIR \t$f" | sed s!$trashdir/files/!!
    else
      echo -e "FILE\t$f" | sed s!$trashdir/files/!!
    fi
  done
  
  for f in $trashdir/files/.* ; do
    
    if [ "$f" = "$trashdir/files/." ] || [ "$f" = "$trashdir/files/.." ] ; then
      continue
    fi
    
    if [ -d $f ] ; then
      echo -e "DIR \t$f" | sed s!$trashdir/files/!!
    else
      echo -e "FILE\t$f" | sed s!$trashdir/files/!!
    fi
  done
}

function trashInfo
{
  for f in $trashdir/files/* ; do
    local a=`echo $f | sed s!$trashdir/files/!!`
    if [ "$a" = "*" ] ; then
      echo The trash-can is empty.
      exit
    fi
    echo File=$a
    sed s/"\[Trash Info\]"/======================/ < $trashdir/info/$a.trashinfo
    echo -e "======================\n"
  done
  
  for f in $trashdir/files/.* ; do
  
    if [ "$f" = "$trashdir/files/." ] || [ "$f" = "$trashdir/files/.." ] ; then
      continue
    fi
    
    local a=`echo $f | sed s!$trashdir/files/!!`
    echo File=$a
    sed s/"\[Trash Info\]"/======================/ < $trashdir/info/$a.trashinfo
    echo -e "======================\n"
  done
}

function trashDelete #$1 = file to be deleted
{
  if [ "$1" = "" ] ; then
    trashHelp
    exit
  fi
  
  if [ ! -e $trashdir/files/$1 ] ; then
    echo "That file is not in the trash-can."
    exit
  fi
  
  echo "Are you sure you want to permanently delete file \"$1\"? (Y/n)"
  read confirm
  
  if [ ! "$confirm" = "Y" ] ; then
    exit
  fi
  
  rm --force -r $trashdir/files/$1
  rm $trashdir/info/$1.trashinfo
}

function fullFilename #$1 = filename to be resolved
{
  local python=$(which python)
  
  orig=$(${python} -c 'import os;print(os.path.realpath("'"$1"'"));')
}

function shortFilename #$1 = filename to be resolved
{
  short=$(basename $1)
}

function trashMoveToTrash #$1 = file to be trashed
{
  fullFilename $1 #goes in $orig
  shortFilename $1 #goes in $short
  local date=$(date +"%Y-%m-%dT%H:%M:%S")

  mv --force $orig $trashdir/files/$short
  echo -e "[Trash Info]\nPath=$orig\nDeletionDate=$date" > $trashdir/info/$short.trashinfo
}

function trashTrash
{
  if [ $# = 1 ] ; then
    trashHelp
    exit
  fi
  
  local files=( $@ )
  for ((i=1;i<${#files[@]};i++)) ; do
    trashMoveToTrash ${files[$i]}
  done
}

function trashRestore #$1 = file to be restored
{
  if [ "$1" = "" ] ; then
    trashHelp
    exit
  fi
  
  if [ ! -f "$trashdir/info/$1.trashinfo" ] ; then
    echo "File is not in the trash-can."
    exit
  else
    while read line
    do
      if [[ ${line:0:5} = "Path=" ]] ; then
        path=${line:5}
        mv $trashdir/files/$1 $path
        rm $trashdir/info/$1.trashinfo
        break
      fi
    done < $trashdir/info/$1.trashinfo
  fi
}

function trashEmpty #$1 = '-yes' if silent deletion is enabled
{
  if [ ! "$1" = "-yes" ] ; then
    echo "Are you sure you want to empty the trash-can? (Y/n)"
    read confirm
    if [ "$confirm" != "Y" ] ; then
      exit
    fi
  fi
  
  rm -r -f $trashdir/files/* $trashdir/info/*
  
  for f in $trashdir/files/.* ; do
    
    if [ "$f" = "$trashdir/files/." ] || [ "$f" = "$trashdir/files/.." ] ; then
      continue
    fi
    
    rm -r -f $f
  done
  
  for f in $trashdir/info/.* ; do
    
    if [ "$f" = "$trashdir/info/." ] || [ "$f" = "$trashdir/info/.." ] ; then
      continue
    fi
    
    rm -r -f $f
  done
}

if [ $# = 0 ] ; then
  trashHelp
  exit
else
  case $1 in
    display)
      trashDisplay ;;
    info)
      trashInfo ;;
    delete)
      trashDelete $2 ;;
    trash)
      trashTrash $@ ;;
    restore)
      trashRestore $2 ;;
    empty)
      trashEmpty $2 ;;
    *)
      trashHelp ;;
  esac
fi
